package org.shopen.ai.puremvc.view.project
{
	import flash.events.Event;
	
	import mx.collections.ArrayCollection;
	
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;
	import org.shopen.ai.puremvc.ApplicationConstants;
	import org.shopen.ai.puremvc.model.algo.AlgoProxy;
	import org.shopen.ai.puremvc.model.algo.ISearchAlgo;
	import org.shopen.ai.puremvc.model.problem.IState;
	import org.shopen.ai.puremvc.model.settings.ICommitSettingsResult;
	import org.shopen.ai.puremvc.model.settings.ManualSettings;
	import org.shopen.ai.puremvc.model.settings.PerformModeType;
	import org.shopen.ai.puremvc.model.settings.SettingsProxy;
	import org.shopen.ai.puremvc.view.project.components.ManualSetupView;
	import org.shopen.ai.puremvc.view.project.events.DataChangedEvent;

	public class ManualSetupViewMediator extends Mediator
	{
		public static const NAME : String = "ManualSetupViewMediator";
		
		public function get manualSetupView() : ManualSetupView
		{
			var result : ManualSetupView = viewComponent as ManualSetupView;
			return result;
		}
		
		protected var initialState : IState = null;
		protected var goalState : IState 	= null;
		
		public function ManualSetupViewMediator(viewComponent : ManualSetupView = null)
		{
			super(ManualSetupViewMediator.NAME, viewComponent);
		}
		
		override public function getMediatorName():String
		{
			return ManualSetupViewMediator.NAME;
		}
		
		override public function onRegister():void
		{
			initializeView();
			addEventListeners();
			sendNotification(ApplicationConstants.INITIALIZE_MANUAL_SETTINGS, null, ApplicationConstants.MANUAL_SETTINGS_TYPE);
		}
		
		protected function initializeView() : void
		{
			manualSetupView.algoLabelField = "title";
			manualSetupView.performModeLabelField = "name"
		}
		
		protected function addEventListeners() : void
		{
			manualSetupView.addEventListener(ManualSetupView.DELAY_CHANGED, onDelayChanged);
			manualSetupView.addEventListener(ManualSetupView.PERFORMMODE_CHANGED, onPerformModeChanged);
			manualSetupView.addEventListener(ManualSetupView.SEARCHALGO_CHANGED, onSearchAlgoChanged);
			
			manualSetupView.addEventListener(ManualSetupView.SELECTINITIALSTATE_CLICKED, onSelectInitialStateClicked);
			manualSetupView.addEventListener(ManualSetupView.SELECTGOALSTATE_CLICKED, onSelectGoalStateClicked);
		}
		
		private function onDelayChanged(event : DataChangedEvent) : void
		{
			commitSetting(getSettings());
		}
		
		private function onSearchAlgoChanged(event : DataChangedEvent) : void
		{
			commitSetting(getSettings());
		}
		
		private function onPerformModeChanged(event : DataChangedEvent) : void
		{
			manualSetupView.delayEnabled = manualSetupView.selectedMode == PerformModeType.SLIDESHOW;
			commitSetting(getSettings());
		}
		
		private function onSelectInitialStateClicked(event : Event) : void
		{
			sendNotification(ApplicationConstants.SELECT_STATE, manualSetupView, ApplicationConstants.INITIAL_STATE_TYPE);
		}
		
		private function onSelectGoalStateClicked(event : Event) : void
		{
			sendNotification(ApplicationConstants.SELECT_STATE, manualSetupView, ApplicationConstants.GOAL_STATE_TYPE);
		}
		
		protected function getSettings() : ManualSettings
		{
			var algo : ISearchAlgo = manualSetupView.selectedAlgo as ISearchAlgo;
			var performMode : PerformModeType = manualSetupView.selectedMode as PerformModeType;
			var delay : uint = manualSetupView.delay;
			var settings : ManualSettings = new ManualSettings(initialState, goalState, algo, performMode, delay);
			return settings;
		}
		protected function setSettings(settings : ManualSettings) : void
		{
			if (settings.initialState != null)
			{
				manualSetupView.initialStateLabel = settings.initialState.toString();
				initialState = settings.initialState;
			}
			if (settings.goalState != null)
			{
				manualSetupView.goalStateLabel = settings.goalState.toString();
				goalState = settings.goalState;
			}
			manualSetupView.selectedAlgo = settings.algo;
			manualSetupView.selectedMode = settings.performMode;
			manualSetupView.delay = settings.delay;
		}
		
		protected function commitSetting(settings : ManualSettings) : void
		{
			sendNotification(ApplicationConstants.COMMIT_MANUAL_SETTINGS, settings);
		}
		
		override public function listNotificationInterests():Array
		{
			return [AlgoProxy.ALGORITHMS_LOADED,
					SettingsProxy.PERFORMMODES_LOADED,
					SettingsProxy.COMMIT_MANUALSETTINGS_RESULT,
					SettingsProxy.MANUALSETTINGS_LOADED,
					SettingsProxy.MANUALSETTINGS_CHANGED,
					ApplicationConstants.PROBLEMSTATE_SELECTED];
		}
		
		override public function handleNotification(notification:INotification):void
		{
			var name : String = notification.getName();
			var type : String = notification.getType();
			switch (name)
			{
				case AlgoProxy.ALGORITHMS_LOADED:
					if (type == ApplicationConstants.MANUAL_SETTINGS_TYPE)
					{
						var algorithms : ArrayCollection = notification.getBody() as ArrayCollection;
						manualSetupView.algoDataSource = algorithms;
					}
					break;
				case SettingsProxy.PERFORMMODES_LOADED:
					if (type == ApplicationConstants.MANUAL_SETTINGS_TYPE)
					{
						var performModes : ArrayCollection = notification.getBody() as ArrayCollection;
						manualSetupView.performModeDataSource = performModes;
					}
					break;
				case SettingsProxy.MANUALSETTINGS_LOADED:
				case SettingsProxy.MANUALSETTINGS_CHANGED:
					setSettings(notification.getBody() as ManualSettings);
					break;
				case SettingsProxy.COMMIT_MANUALSETTINGS_RESULT:
					var commitResult : ICommitSettingsResult = notification.getBody() as ICommitSettingsResult;
					manualSetupView.setValidation(commitResult.isValid, commitResult.toString());
					break;
				case ApplicationConstants.PROBLEMSTATE_SELECTED:
					var state : IState = notification.getBody() as IState;
					if (type == ApplicationConstants.INITIAL_STATE_TYPE)
					{
						manualSetupView.initialStateLabel = state.toString();
						this.initialState = state;
						commitSetting(getSettings());
					}
					else if (type == ApplicationConstants.GOAL_STATE_TYPE)
					{
						manualSetupView.goalStateLabel = state.toString();
						this.goalState = state;
						commitSetting(getSettings());
					}
					break;
			}
		}
	}
}